home *** CD-ROM | disk | FTP | other *** search
/ PD ROM 1 / PD ROM Volume I - Macintosh Software from BMUG (1988).iso / Graphics / Graphic Demos / Stair Draw / source / Stair_Program < prev   
Encoding:
Text File  |  1987-01-18  |  19.0 KB  |  895 lines  |  [TEXT/PJMM]

  1. {** STAIR PROGRAM **}
  2. {Program to layout and draw stair section    }
  3. {Version 0.90     01/18/87      G. Langdon    }
  4.  
  5. {**   WINDOWS, MENUS, DIALOGS, & STAIR ROUTINES   **    }
  6. {This unit does the following:                                    }
  7. {    1.    Initializes the Window, Menus,  Controls & Dialogs.     }
  8. {    2.    Sets their default values.                                }
  9. {    3.    Calculates the stair components.                        }
  10. {    4.    Determines whether stair is to be layed out in         }
  11. {        a straight or U-type run.                                 }
  12. {    5.    Draws the stair section in the window.                    }
  13. {    6.  Saves the stair drawing in PICT format on default        }
  14. {        volume.                                                    }
  15.  
  16. UNIT Stair_Program;
  17.  
  18. INTERFACE
  19.  
  20.   {Use the global constants, types and variables...}
  21.     USES
  22.         Stair_Globals;
  23.  
  24.    {Low level initialization routines...}
  25.     PROCEDURE SetUpMenus;
  26.     PROCEDURE SetUpWindow;
  27.     PROCEDURE SetDefaults;
  28.     PROCEDURE UpdateSys;
  29.  
  30.  
  31.    {Routines to convert between number types...}
  32.     PROCEDURE ConvertToExtended (theAns : Str255;
  33.                                     VAR theNum : Extended);
  34.     PROCEDURE ConvertToLongint (theNum : Extended;
  35.                                     VAR theLongint : Longint);
  36.  
  37.   {Routines to calculate layout of stair...}
  38.     PROCEDURE CalcTotHt;
  39.     PROCEDURE CalcRisers;
  40.     PROCEDURE CalcTreads;
  41.  
  42.    {Routines to display layout calculations in the window...}
  43.     PROCEDURE WriteStr (h, v : INTEGER;
  44.                                     theStr : Str255);
  45.     PROCEDURE WriteNum (h, v : INTEGER;
  46.                                     theNum : Extended);
  47.     PROCEDURE DisplayInfo;
  48.  
  49.    {Routines to draw the stair section...}
  50.     PROCEDURE GetTheStair (VAR StairType : INTEGER);
  51.     FUNCTION ConvertToPixels (theDim : Extended) : INTEGER;
  52.     PROCEDURE DrawTopLanding (StairType : INTEGER);
  53.     PROCEDURE DrawMidLanding (StairType : INTEGER);
  54.     PROCEDURE DrawBtmLanding (StairType : INTEGER);
  55.     PROCEDURE DrawTopRun (StairType : INTEGER);
  56.     PROCEDURE DrawBtmRun (StairType : INTEGER);
  57.     PROCEDURE DrawStair;
  58.  
  59.  
  60.   {Routines to implement the dialog...}
  61.     FUNCTION CtlHdl (theItem : INTEGER) : ControlHandle;
  62.     PROCEDURE SetUpDialog;
  63.     PROCEDURE SetRadBtn (theItem : INTEGER);
  64.     PROCEDURE UpdateDefaults;
  65.     PROCEDURE DoDialog;
  66.     PROCEDURE RunDialog;
  67.  
  68.    {Routines to implement the window and its actions...}
  69.     PROCEDURE GetPict;
  70.     PROCEDURE UpdatePic (theWindow : WindowPtr;
  71.                                     URgn : RgnHandle);
  72.     PROCEDURE SavePic;
  73.     PROCEDURE ScrAction (theCtl : ControlHandle;
  74.                                     partCode : INTEGER);
  75.     PROCEDURE WindowScroll (theWindow : WindowPtr;
  76.                                     thePt : Point);
  77.     PROCEDURE WindowGrow (theWindow : WindowPtr);
  78.     PROCEDURE DoGoAway (theWindow : WindowPtr);
  79.     PROCEDURE WindowUpdate (theWindow : WindowPtr);
  80.  
  81.    {Routines to implement the menus and their actions...}
  82.     PROCEDURE QuitFile;
  83.     PROCEDURE ClearWindow;
  84.     PROCEDURE DoAppleMenu (theItem : INTEGER);
  85.     PROCEDURE DoFileMenu (theItem : INTEGER);
  86.     PROCEDURE DoEditMenu (theItem : INTEGER);
  87.     PROCEDURE DoScaleMenu (theItem : INTEGER);
  88.     PROCEDURE DoPenMenu (theItem : INTEGER);
  89.     PROCEDURE SelectMenu (selection : LongInt);
  90.     PROCEDURE KeyEvent (theKey : Char);
  91.  
  92.   {Setup the overall system...}
  93.     PROCEDURE SetUpSys;
  94.  
  95.  
  96. IMPLEMENTATION
  97.  
  98. {**** BEGINNING OF STAIR PROGRAM ****}
  99.  
  100.     PROCEDURE SetUpMenus;
  101.         VAR
  102.             I : INTEGER;
  103.     BEGIN
  104.           {Open menu resources...}
  105.         InitMenus;
  106.          {Assign menu handles to menu array...}
  107.         theMenus[1] := GetMenu(AppleMenu);
  108.         theMenus[2] := GetMenu(FileMenu);
  109.         theMenus[3] := GetMenu(EditMenu);
  110.         theMenus[4] := GetMenu(ScaleMenu);
  111.         theMenus[5] := GetMenu(PenMenu);
  112.          {Add Desk Accessories to AppleMenu...}
  113.         AddResMenu(theMenus[1], 'DRVR');
  114.         FOR I := 1 TO lastMenu DO
  115.             InsertMenu(theMenus[I], 0);
  116.         {Draw the menu titles in the menu bar...}
  117.         DrawMenuBar;
  118.     END;
  119.  
  120.     PROCEDURE SetUpWindow;
  121.     BEGIN
  122.        {Open resource file defining the drawing window...            }
  123.        {Define region and rectangles for use with the window...    }
  124.         DrawWindow := GetNewWindow(256, NIL, POINTER(-1));
  125.         vsBar := GetNewControl(258, DrawWindow);
  126.         HiliteControl(vsBar, 255);
  127.         hsBar := GetNewControl(257, DrawWindow);
  128.         HiliteControl(hsBar, 255);
  129.         URgn := NewRgn;
  130.         SetRect(PicBnds, 0, 0, 662, 442);
  131.         SetRect(SizeBnds, 50, 50, 512, 342);
  132.         SetRect(DragBnds, 4, 24, 508, 338);
  133.     END;
  134.  
  135.     PROCEDURE SetDefaults;
  136.     BEGIN
  137.        {Set initial value of pixels per inch...}
  138.         pixelIn := 1.58333;
  139.        {Set initial value of drawing pen...}
  140.         penWidth := 1;
  141.         penHeight := 1;
  142.        {Set initial values for dialog items...}
  143.         FtAns := '';
  144.         InAns := '';
  145.         RGroup[1].min := StrtBtn;
  146.         RGroup[1].max := UTypeBtn;
  147.         RGroup[1].default := UTypeBtn;
  148.         RGroup[2].min := TopBtn;
  149.         RGroup[2].max := BtmBtn;
  150.         RGroup[2].default := BtmBtn;
  151.     END;
  152.  
  153.     PROCEDURE UpdateSys;
  154.     BEGIN
  155.         SystemTask;
  156.     END;
  157.  
  158.     PROCEDURE ConvertToExtended;
  159.         VAR
  160.             longNum : Longint;
  161.             logNum : extended;
  162.     BEGIN
  163.         {Check that a decimal numer was not entered...}
  164.         IF pos('.', theAns) = 0 THEN
  165.             BEGIN
  166.             {Convert the answer string to a longint number...}
  167.                 StringToNum(theAns, longNum);
  168.             {Convert the longint to an number of type extended...}
  169.                 logNum := exp(longNum);
  170.                 theNum := ln(logNum);
  171.             END
  172.         ELSE
  173.             theItem := CautionAlert(1002, NIL);
  174.     END;
  175.  
  176.     PROCEDURE ConvertToLongint;
  177.     BEGIN
  178.     {Convert the extended number to a number of type Longint...}
  179.         theLongint := round(theNum);
  180.     END;
  181.  
  182.     PROCEDURE CalcTotHt;
  183.     BEGIN
  184.         ConvertToExtended(FtAns, Feet);
  185.         ConvertToExtended(InAns, Inches);
  186.         Ht := (Feet * 12.00) + Inches;
  187.     END;
  188.  
  189.     PROCEDURE CalcRisers;
  190.     BEGIN
  191.         Risers := Ht / StdRiser;
  192.         AdjRisers := round(Risers) + 1;
  193.         RiserDim := Ht / AdjRisers;
  194.     END;
  195.  
  196.     PROCEDURE CalcTreads;
  197.     BEGIN
  198.         Treads := adjRisers - 1;
  199.         IF (RiserDim < 5.99) THEN
  200.             TreadDim := 12.00;
  201.         IF (RiserDim >= 6.00) AND (RiserDim <= 6.99) THEN
  202.             TreadDim := 11.50;
  203.         IF (RiserDim >= 7.00) AND (RiserDim <= 7.12) THEN
  204.             TreadDim := 11.00;
  205.         IF (RiserDim >= 7.13) AND (RiserDim <= 7.24) THEN
  206.             TreadDim := 10.75;
  207.         IF (RiserDim >= 7.25) AND (RiserDim <= 7.37) THEN
  208.             TreadDim := 10.50;
  209.         IF (RiserDim >= 7.38) AND (RiserDim <= 7.49) THEN
  210.             TreadDim := 10.25;
  211.         IF (RiserDim >= 7.5) THEN
  212.             TreadDim := 10.00;
  213.     END;
  214.  
  215.     PROCEDURE GetTheStair;
  216.         VAR
  217.             StairShape, LongerAt : INTEGER;
  218.     BEGIN
  219.         StairShape := SelectedCtl[1].value;
  220.         LongerAt := SelectedCtl[2].value;
  221.         CASE StairShape OF
  222.             UTypeBtn : 
  223.                 IF (AdjRisers MOD 2 = 0) THEN
  224.                     BEGIN
  225.                         StairType := 1;
  226.                     END
  227.                 ELSE
  228.                     BEGIN
  229.                         CASE LongerAt OF
  230.                             BtmBtn : 
  231.                                 StairType := 2;
  232.                             TopBtn : 
  233.                                 StairType := 3;
  234.                         END;
  235.                     END;
  236.             StrtBtn : 
  237.                 BEGIN
  238.                     IF Ht < 144 THEN
  239.                         StairType := 4
  240.                     ELSE
  241.                         BEGIN
  242.                             IF (AdjRisers MOD 2 = 0) THEN
  243.                                 BEGIN
  244.                                     StairType := 5;
  245.                                 END
  246.                             ELSE
  247.                                 BEGIN
  248.                                     CASE LongerAt OF
  249.                                         BtmBtn : 
  250.                                             StairType := 6;
  251.                                         TopBtn : 
  252.                                             StairType := 7;
  253.                                     END;
  254.                                 END;
  255.                         END;
  256.                 END;
  257.             OTHERWISE
  258.                 ;
  259.         END;
  260.     END;
  261.  
  262.     FUNCTION ConvertToPixels;
  263.     BEGIN
  264.         ConvertToPixels := round(theDim * pixelIn);
  265.     END;
  266.  
  267.     PROCEDURE DrawTopLanding;
  268.         VAR
  269.             Landing, Tread : INTEGER;
  270.     BEGIN
  271.         Landing := ConvertToPixels(LandingDim);
  272.         Tread := ConvertToPixels(TreadDim);
  273.         CASE StairType OF
  274.             1, 2, 3, 4, 5, 6, 7 : 
  275.                 line((Landing - Tread), 0);
  276.             OTHERWISE
  277.                 ;
  278.         END;
  279.     END;
  280.  
  281.     PROCEDURE DrawTopRun;
  282.         VAR
  283.             Riser, Tread, Nosing, Steps, Run : INTEGER;
  284.     BEGIN
  285.         Riser := ConvertToPixels(RiserDim);
  286.         Tread := ConvertToPixels(TreadDim);
  287.         Nosing := ConvertToPixels(NosingDim);
  288.         CASE StairType OF
  289.             1, 2, 5, 6 :   {Even number of risers with equal stair runs}
  290.                 Run := (AdjRisers DIV 2);
  291.             3, 7 :           {Odd number of risers with longer stair run at top}
  292.                 Run := (AdjRisers DIV 2) + 1;
  293.             4 :                {Stair less than 12 ft, so only one stair run}
  294.                 Run := AdjRisers;
  295.             OTHERWISE
  296.                 ;
  297.         END;
  298.         CASE StairType OF
  299.             1, 2, 3, 4, 5, 6, 7 :    {Draw stair run to right for all cases}
  300.                 BEGIN
  301.                     FOR Steps := 1 TO Run DO
  302.                         BEGIN
  303.                             line(Tread, 0);
  304.                             line(0, Nosing);
  305.                             line(-Nosing, 0);
  306.                             line(0, (Riser - Nosing));
  307.                         END;
  308.                 END;
  309.             OTHERWISE
  310.                 ;
  311.         END;
  312.     END;
  313.  
  314.     PROCEDURE DrawMidLanding;
  315.         VAR
  316.             Landing, Tread, Nosing : INTEGER;
  317.     BEGIN
  318.         Landing := ConvertToPixels(LandingDim);
  319.         Tread := ConvertToPixels(TreadDim);
  320.         Nosing := ConvertToPixels(NosingDim);
  321.         CASE StairType OF
  322.             1, 2, 3 :    {Draw landing to right then return to left}
  323.                 BEGIN
  324.                     line(Landing, 0);
  325.                     line(-(Landing - Tread + Nosing), 0);
  326.                 END;
  327.             4 : 
  328.                 ;             {Stair less than 12 ft so no middle landing}
  329.             5, 6, 7 :    {Draw landing to right, just like Top Landing}
  330.                 DrawTopLanding(1);
  331.             OTHERWISE
  332.                 ;
  333.         END;
  334.     END;
  335.  
  336.     PROCEDURE DrawBtmRun;
  337.         VAR
  338.             Riser, Tread, Nosing, Steps, Run : INTEGER;
  339.     BEGIN
  340.         Riser := ConvertToPixels(RiserDim);
  341.         Tread := ConvertToPixels(TreadDim);
  342.         Nosing := ConvertToPixels(NosingDim);
  343.         CASE StairType OF
  344.             1, 3, 5, 7 :   {Even number of risers with equal stair runs}
  345.                 Run := (AdjRisers DIV 2);
  346.             2, 6 :       {Odd number of risers with longer stair run at bottom}
  347.                 Run := (AdjRisers DIV 2) + 1;
  348.             4 : 
  349.                 ;                {Stair less than 12 ft so no bottom run}
  350.             OTHERWISE
  351.                 ;
  352.         END;
  353.         CASE StairType OF
  354.             1, 2, 3 :    {Draw stair run to left for U-type stairs}
  355.                 BEGIN
  356.                     FOR Steps := 1 TO Run DO
  357.                         BEGIN
  358.                             line(-Tread, 0);
  359.                             line(0, Nosing);
  360.                             line(Nosing, 0);
  361.                             line(0, (Riser - Nosing));
  362.                         END;
  363.                 END;
  364.             5, 6, 7 :     {Draw stair run to right for straight stairs}
  365.                 BEGIN
  366.                     FOR Steps := 1 TO Run DO
  367.                         BEGIN
  368.                             line(Tread, 0);
  369.                             line(0, Nosing);
  370.                             line(-Nosing, 0);
  371.                             line(0, (Riser - Nosing));
  372.                         END;
  373.                 END;
  374.             4 : 
  375.                 ;              {Stair less than 12 ft so no bottom run}
  376.             OTHERWISE
  377.                 ;
  378.         END;
  379.     END;
  380.  
  381.     PROCEDURE DrawBtmLanding;
  382.         VAR
  383.             Landing : INTEGER;
  384.     BEGIN
  385.         Landing := ConvertToPixels(LandingDim);
  386.         CASE StairType OF
  387.             1, 2, 3 :        {Draw landing to the left for U-type stairs}
  388.                 BEGIN
  389.                     line(-Landing, 0);
  390.                 END;
  391.             4, 5, 6, 7 :   {Draw landing to the right for straight stairs}
  392.                 BEGIN
  393.                     line(Landing, 0);
  394.                 END;
  395.             OTHERWISE
  396.                 ;
  397.         END;
  398.     END;
  399.  
  400.     PROCEDURE DrawStair;
  401.     BEGIN
  402.         IF Ht <> 0 THEN
  403.             BEGIN
  404.                 SetPort(DrawWindow);
  405.                 PenSize(penWidth, penHeight);
  406.                 GettheStair(StairType);
  407.                 MoveTo(10, 10);
  408.                 DrawTopLanding(StairType);
  409.                 DrawTopRun(StairType);
  410.                 DrawMidLanding(StairType);
  411.                 DrawBtmRun(StairType);
  412.                 DrawBtmLanding(StairType);
  413.                 PenNormal;
  414.             END
  415.         ELSE
  416.     END;
  417.  
  418.     PROCEDURE WriteStr;
  419.     BEGIN
  420.         Moveto(h, v);
  421.         DrawString(theStr);
  422.     END;
  423.  
  424.     PROCEDURE WriteNum;
  425.     BEGIN
  426.         MoveTo(h, v);
  427.         WriteDraw(theNum : 5 : 2);
  428.     END;
  429.  
  430.     PROCEDURE DisplayInfo;
  431.     BEGIN
  432.         CalcTotHt;
  433.         CalcRisers;
  434.         CalcTreads;
  435.         IF Ht <> 0 THEN
  436.             BEGIN
  437.                 WriteStr(300, 20, 'Stair Height:');
  438.                 WriteNum(380, 20, Feet);
  439.                 WriteStr(415, 20, 'Ft,');
  440.                 WriteNum(435, 20, Inches);
  441.                 WriteStr(469, 20, 'In');
  442.                 WriteStr(300, 35, 'Total Height:');
  443.                 WriteNum(380, 35, Ht);
  444.                 WriteStr(422, 35, 'In');
  445.                 WriteStr(300, 50, 'Total Risers:');
  446.                 WriteNum(380, 50, AdjRisers);
  447.                 WriteStr(300, 65, 'Riser Height:');
  448.                 WriteNum(380, 65, RiserDim);
  449.                 WriteStr(412, 65, 'In');
  450.                 WriteStr(300, 80, 'Total Treads:');
  451.                 WriteNum(380, 80, Treads);
  452.                 WriteStr(300, 95, 'Tread Depth:');
  453.                 WriteNum(380, 95, TreadDim);
  454.                 WriteStr(412, 95, 'In');
  455.             END
  456.         ELSE
  457.     END;
  458.  
  459.     FUNCTION CtlHdl;
  460.     BEGIN
  461.         GetDItem(theDialog, theItem, theType, ItemHdl, ItemBox);
  462.         CtlHdl := ControlHandle(ItemHdl);
  463.     END;
  464.  
  465.     PROCEDURE SetUpDialog;
  466.         VAR
  467.             I, J : INTEGER;
  468.     BEGIN
  469.         theDialog := GetNewDialog(1000, NIL, POINTER(-1));
  470.         FOR I := 1 TO numRGroups DO
  471.             FOR J := RGroup[I].min TO RGroup[I].max DO
  472.                 BEGIN
  473.                     SetCRefCon(CtlHdl(J), I);
  474.                     SetCtlValue(CtlHdl(J), ORD(J = RGroup[I].default));
  475.                 END;
  476.         SetIText(Handle(CtlHdl(FtTxt)), FtAns);
  477.         SetIText(Handle(CtlHdl(InTxt)), InAns);
  478.         SelIText(theDialog, FtTxt, length(FtAns), length(FtAns));
  479.     END;
  480.  
  481.     PROCEDURE SetRadBtn;
  482.         VAR
  483.             I, J : INTEGER;
  484.     BEGIN
  485.         I := GetCRefCon(CtlHdl(theItem));
  486.         FOR J := RGroup[I].min TO RGroup[I].max DO
  487.             SetCtlValue(CtlHdl(J), ORD(J = theItem));
  488.     END;
  489.  
  490.     PROCEDURE UpdateDefaults;
  491.         VAR
  492.             I, J : INTEGER;
  493.     BEGIN
  494.         FOR I := 1 TO numRGroups DO
  495.             FOR J := RGroup[I].min TO RGroup[I].max DO
  496.                 IF GetCtlValue(CtlHdl(J)) = 1 THEN
  497.                     BEGIN
  498.                         RGroup[I].default := J;
  499.                         SelectedCtl[I].value := J;
  500.                     END;
  501.         GetIText(Handle(CtlHdl(FtTxt)), FtAns);
  502.         GetIText(Handle(CtlHdl(InTxt)), InAns);
  503.     END;
  504.  
  505.     PROCEDURE DoDialog;
  506.     BEGIN
  507.         FlushEvents(everyEvent, 0);
  508.         REPEAT
  509.             ModalDialog(NIL, itemHit);
  510.             CASE itemHit OF
  511.                 StrtBtn : 
  512.                     BEGIN
  513.                         SetRadBtn(itemHit);
  514.                     END;
  515.                 UTypeBtn : 
  516.                     BEGIN
  517.                         SetRadBtn(itemHit);
  518.                     END;
  519.                 TopBtn : 
  520.                     BEGIN
  521.                         SetRadBtn(itemHit);
  522.                     END;
  523.                 BtmBtn : 
  524.                     BEGIN
  525.                         SetRadBtn(itemHit);
  526.                     END;
  527.                 OTHERWISE
  528.                     ;
  529.             END;
  530.         UNTIL (itemHit = OKBtn) OR (itemHit = CancelBtn);
  531.         IF itemHit = OKBtn THEN
  532.             UpdateDefaults;
  533.         IF itemHit = CancelBtn THEN
  534.             ;
  535.     END;
  536.  
  537.     PROCEDURE RunDialog;
  538.     BEGIN
  539.         ClearWindow;
  540.         SetUpDialog;
  541.         DoDialog;
  542.         DisposDialog(theDialog);
  543.         IF itemHit = OKBtn THEN
  544.             BEGIN
  545.                 GetPict;
  546.                 IF NOT FirstDialog THEN
  547.                     UpdatePic(DrawWindow, URgn);
  548.                 WindowUpdate(DrawWindow);
  549.             END;
  550.         IF itemHit = CancelBtn THEN
  551.             BEGIN
  552.                 GetPict;
  553.                 IF NOT FirstDialog THEN
  554.                     UpdatePic(DrawWindow, URgn);
  555.                 WindowUpdate(DrawWindow);
  556.             END;
  557.     END;
  558.  
  559.     PROCEDURE GetPict;
  560.     BEGIN
  561.         SetPort(DrawWindow);
  562.         TextFont(Geneva);
  563.         TextFace([bold]);
  564.         TextSize(9);
  565.         ClipRect(PicBnds);
  566.         Pict := OpenPicture(PicBnds);
  567.         DisplayInfo;
  568.         DrawStair;
  569.         ClosePicture;
  570.     END;
  571.  
  572.     PROCEDURE UpdatePic;
  573.         VAR
  574.             S : Point;
  575.     BEGIN
  576.         SetPt(S, GetCtlValue(hsBar), GetCtlValue(vsBar));
  577.         SetOrigin(S.h, S.v);
  578.         OffsetRgn(URgn, S.h, S.v);
  579.         SetClip(URgn);
  580.         EraseRgn(URgn);
  581.         Hlock(Handle(Pict));
  582.         DrawPicture(Pict, PicBnds);
  583.         HUnlock(Handle(Pict));
  584.         SetOrigin(0, 0);
  585.         ClipRect(thePort^.portRect);
  586.         DrawControls(theWindow);
  587.     END;
  588.  
  589.     PROCEDURE SavePic;
  590.         VAR
  591.             theFile : fileName;
  592.     BEGIN
  593.         theItem := CautionAlert(1003, NIL);
  594.         CASE theItem OF
  595.             1 : 
  596.                 BEGIN
  597.                     theFile := 'Stair Disk:Stair Drawing';
  598.                     SaveDrawing(theFile);
  599.                 END;
  600.             2 : 
  601.                 ;
  602.             OTHERWISE
  603.                 ;
  604.         END;
  605.     END;
  606.  
  607.     PROCEDURE ScrAction;
  608.         VAR
  609.             PageSize, Delta : INTEGER;
  610.             S, dS : Point;
  611.             ViewBnds : Rect;
  612.     BEGIN
  613.         WITH thePort^.portRect DO
  614.             CASE GetCRefCon(theCtl) OF
  615.                 1 : 
  616.                     PageSize := (right - left - 16) DIV 2;
  617.                 2 : 
  618.                     PageSize := (bottom - top - 16) DIV 2;
  619.                 OTHERWISE
  620.                     ;
  621.             END;
  622.         CASE partCode OF
  623.             inUpButton : 
  624.                 Delta := -ScrollSize;
  625.             inDownButton : 
  626.                 Delta := +ScrollSize;
  627.             inPageUp : 
  628.                 Delta := -PageSize;
  629.             inPageDown : 
  630.                 Delta := +PageSize;
  631.             OTHERWISE
  632.                 ;
  633.         END;
  634.         SetPt(S, GetCtlValue(hsBar), GetCtlValue(vsBar));
  635.         SetCtlValue(theCtl, GetCtlValue(theCtl) + Delta);
  636.         SetPt(dS, S.h - GetCtlValue(hsBar), S.v - GetCtlValue(vsBar));
  637.         WITH thePort^.portRect DO
  638.             SetRect(ViewBnds, left, top, right - 15, bottom - 15);
  639.         ScrollRect(ViewBnds, dS.h, dS.v, URgn);
  640.         UpdatePic(DrawWindow, URgn);
  641.     END;
  642.  
  643.  
  644.     PROCEDURE WindowScroll;
  645.         VAR
  646.             theCtl : ControlHandle;
  647.     BEGIN
  648.         IF theWindow = FrontWindow THEN
  649.             BEGIN
  650.                 SetPort(theWindow);
  651.                 GlobalToLocal(thePt);
  652.                 CASE FindControl(thePt, theWindow, theCtl) OF
  653.                     inUpButton, inDownButton, inPageUp, inPageDown : 
  654.                         IF TrackControl(theCtl, thePt, @ScrAction) <> 0 THEN
  655.                             ;
  656.                     inThumb : 
  657.                         IF TrackControl(theCtl, thePt, NIL) <> 0 THEN
  658.                             BEGIN
  659.                                 WITH theWindow^.portRect DO
  660.                                     SetRectRgn(URgn, left, top, right - 15, bottom - 15);
  661.                                 UpdatePic(theWindow, URgn);
  662.                             END;
  663.                     OTHERWISE
  664.                         ;
  665.                 END;
  666.             END
  667.         ELSE
  668.             BEGIN
  669.                 SelectWindow(theWindow);
  670.                 DrawGrowIcon(theWindow);
  671.                 DrawControls(theWindow);
  672.             END;
  673.     END;
  674.  
  675.     PROCEDURE WindowGrow;
  676.         VAR
  677.             WSize : Longint;
  678.             S : Point;
  679.     BEGIN
  680.         WSize := GrowWindow(theWindow, theEvent.where, SizeBnds);
  681.         IF WSize <> 0 THEN
  682.             BEGIN
  683.                 SetPt(S, LoWord(WSize), HiWord(WSize));
  684.                 SizeWindow(theWindow, S.h, S.v, TRUE);
  685.                 SetPort(theWindow);
  686.                 ClipRect(thePort^.portRect);
  687.                 SizeControl(hsBar, S.h - 13, 16);
  688.                 MoveControl(hsBar, -1, S.v - 15);
  689.                 SizeControl(vsBar, 16, S.v - 13);
  690.                 MoveControl(vsBar, S.h - 15, -1);
  691.             END;
  692.     END;
  693.  
  694.     PROCEDURE DoGoAway;
  695.     BEGIN
  696.         IF theWindow <> FrontWindow THEN
  697.             SelectWindow(theWindow)
  698.         ELSE IF TrackGoAway(theWindow, theEvent.where) THEN
  699.             BEGIN
  700.                 IF FrontWindow = theWindow THEN
  701.                     DisposeWindow(theWindow);
  702.             END;
  703.     END;
  704.  
  705.  
  706.     PROCEDURE WindowUpdate;
  707.         VAR
  708.             GrowArea : Rect;
  709.     BEGIN
  710.         SetPort(theWindow);
  711.         WITH thePort^.portRect DO
  712.             SetRect(GrowArea, right - 15, bottom - 15, right, bottom);
  713.         InvalRect(GrowArea);
  714.         IF theWindow = FrontWindow THEN
  715.             BEGIN
  716.                 HiliteControl(vsBar, 0);
  717.                 HiliteControl(hsBar, 0);
  718.                 ShowControl(vsBar);
  719.                 ShowControl(hsBar);
  720.             END
  721.         ELSE
  722.             BEGIN
  723.                 HideControl(vsBar);
  724.                 HideControl(hsBar);
  725.             END;
  726.         BeginUpdate(theWindow);
  727.         EraseRect(theWindow^.portRect);
  728.         DrawGrowIcon(theWindow);
  729.         DrawControls(theWindow);
  730.         WITH theWindow^.portRect DO
  731.             SetRectRgn(URgn, left, top, right - 15, bottom - 15);
  732.         UpdatePic(theWindow, URgn);
  733.         EndUpdate(theWindow);
  734.     END;
  735.  
  736.     PROCEDURE QuitFile;
  737.     BEGIN
  738.         done := TRUE;
  739.     END;
  740.  
  741.     PROCEDURE ClearWindow;
  742.         VAR
  743.             theScreen : Rect;
  744.     BEGIN
  745.         SetPort(DrawWindow);
  746.         theScreen := thePort^.portRect;
  747. {**EraseRect(theScreen);**}
  748.     END;
  749.  
  750.  
  751.     PROCEDURE DoAppleMenu;
  752.         VAR
  753.             refNum : INTEGER;
  754.             name : Str255;
  755.     BEGIN
  756.         IF theItem = 1 THEN
  757.             theItem := Alert(1001, NIL)
  758.         ELSE
  759.             BEGIN
  760.                 getItem(theMenus[1], theItem, name);
  761.                 refNum := OpenDeskAcc(name);
  762.             END;
  763.     END;
  764.  
  765.     PROCEDURE DoFileMenu;
  766.     BEGIN
  767.         CASE theItem OF
  768.             1 : 
  769.                 BEGIN
  770.                     FirstDialog := FALSE;
  771.                     IF FrontWindow <> NIL THEN
  772.                         DisposeWindow(DrawWindow);
  773.                     SetUpWindow;
  774.                     RunDialog;
  775.                 END;
  776.             5 : 
  777.                 SavePic;
  778.             8 : 
  779.                 QuitFile;
  780.             OTHERWISE
  781.                 ;
  782.         END;
  783.     END;
  784.  
  785.     PROCEDURE DoEditMenu;
  786.     BEGIN
  787.         IF NOT SystemEdit(theItem + 1) THEN
  788.             BEGIN
  789.                 SetPort(DrawWindow);
  790.                 CASE theItem OF
  791.                     4 : 
  792.                         BEGIN
  793.                             ClearWindow;
  794.                         END;
  795.                     OTHERWISE
  796.                         ;
  797.                 END;
  798.             END;
  799.     END;
  800.  
  801.     PROCEDURE DoScaleMenu;
  802.     BEGIN
  803.         CASE theItem OF
  804.             1 :    {Scale 1/8"=1'-0"}
  805.                 BEGIN
  806.                     pixelIn := 1.58333;
  807.                 END;
  808.             2 :    {Scale 1/4"=1'-0"}
  809.                 BEGIN
  810.                     pixelIn := (1.58333 * 2.0);
  811.                 END;
  812.             3 :    {Scale 1/2"=1'-0"}
  813.                 BEGIN
  814.                     pixelIn := (1.58333 * 4.0);
  815.                 END;
  816.             4 :    {Scale 3/4"=1'-0"}
  817.                 BEGIN
  818.                     pixelIn := (1.58333 * 6.0);
  819.                 END;
  820.             OTHERWISE
  821.                 ;
  822.         END;
  823.     END;
  824.  
  825.     PROCEDURE DoPenMenu;
  826.     BEGIN
  827.         CASE theItem OF
  828.             1 :    {Pen Size = 1 pixel}
  829.                 BEGIN
  830.                     penWidth := 1;
  831.                     penHeight := 1;
  832.                 END;
  833.             2 :    {Pen Size = 2 pixel}
  834.                 BEGIN
  835.                     penWidth := 2;
  836.                     penHeight := 2;
  837.                 END;
  838.             3 :     {Pen Size = 3 pixel}
  839.                 BEGIN
  840.                     penWidth := 3;
  841.                     penHeight := 3;
  842.                 END;
  843.             OTHERWISE
  844.                 ;
  845.         END;
  846.     END;
  847.  
  848.     PROCEDURE SelectMenu;
  849.         VAR
  850.             finalTicks : LongInt;
  851.     BEGIN
  852.         HiliteMenu(HiWord(selection));
  853.         Delay(32, finalTicks);
  854.         CASE HiWord(selection) OF
  855.             AppleMenu : 
  856.                 DoAppleMenu(LoWord(selection));
  857.             FileMenu : 
  858.                 DoFileMenu(LoWord(selection));
  859.             EditMenu : 
  860.                 DoEditMenu(LoWord(selection));
  861.             ScaleMenu : 
  862.                 DoScaleMenu(LoWord(selection));
  863.             PenMenu : 
  864.                 DoPenMenu(LoWord(selection));
  865.             OTHERWISE
  866.                 ;
  867.         END;
  868.         HiliteMenu(0);
  869.     END;
  870.  
  871.     PROCEDURE KeyEvent;
  872.     BEGIN
  873.         IF BitTst(@theEvent.modifiers, 7) THEN  {Check for command key}
  874.             SelectMenu(MenuKey(theKey));
  875.     END;
  876.  
  877.     PROCEDURE SetUpSys;
  878.     BEGIN
  879.         InitGraf(@thePort);
  880.         InitFonts;
  881.         InitWindows;
  882.         TEInit;
  883.         InitDialogs(NIL);
  884.         SetDAFont(1);
  885.         SetEventMask(everyEvent);
  886.         FlushEvents(everyEvent, 0);
  887.         SetUpWindow;
  888.         SetUpMenus;
  889.         SetDefaults;
  890.         InitCursor;
  891.         done := FALSE;
  892.         FirstDialog := TRUE;
  893.     END;
  894.  
  895. END.